<!--
禁止修改!此文件是产品代码的一部分，后续可能变更或者不再开放。
若有问题，请参考前端相关二开文档。
-->
<template>
  <div class="home-item-box my-application">
    <div class="header">
      <span>{{ $t('languages.common.workbanch.myApplications') }}</span>
      <span
        v-if="favoritesApps.length > 0"
        class="manage-opt"
        @click="onManageEdit"
        >{{ $t('languages.common.workbanch.management') }}</span>
    </div>
    <LoadingSkeleton v-if="isLoading" :rowNum="2" :type="2" :appNum="4" />
    <template v-else>
      <div v-if="favoritesApps.length > 0" class="app-list">
        <template v-for="(item, index) in favoritesApps">
          <div :key="index" class="list-item" @click="appRoute(item)">
            <div class="app-icon">
              <template v-if="item.content">
                <img :src="'data:image/png;base64,' + item.content" />
              </template>
              <template v-else-if="item.logoUrl">
                <img
                  v-if="item.logoUrl.indexOf('http') > -1"
                  :src="item.logoUrl"
                />
                <img v-else :src="getDownloadUrlNew(item.logoUrl)" />
              </template>
              <img v-else :src="defaultIcon" />
            </div>
            <div class="app-title" :title="getDisplayName(item)">
              {{ getDisplayName(item) }}
            </div>
          </div>
        </template>
      </div>

      <default-content
        v-else
        :title="$t('languages.common.workbanch.applicaion')"
        @openManageModal="onManageEdit"
      />
    </template>
    <h3-popup
      :visible="manageEdit"
      :round="true"
      class="manage-edit-modal"
      maskClosable
      popupDirection="up"
      popupHeight="calc(100% - 44px)"
      @maskClick="popupClose"
    >
      <div class="manage-edit-box">
        <div class="manage-edit-header">
          <div class="manage-edit-name">
            <span>{{
              $t('languages.common.workbanch.manageApplication')
            }}</span>
          </div>
          <div class="close-modal">
            <span
              class="icon aufontAll h-icon-all-close"
              @click="popupClose"
            ></span>
          </div>
        </div>
        <div class="manage-edit-body">
          <div class="body-top">
            <div class="sub-title">
              {{ $t('languages.common.workbanch.added') }}
              <span
                class="count"
                :class="{ selected: selectedApps.length > 0 }"
                >{{ selectedApps.length }}</span>/<span>{{ maxFavoritesApps }}</span>
            </div>
            <div v-if="selectedApps.length > 0" class="sub-content">
              <ul class="app-list">
                <draggable
                  :list="selectedApps"
                  :options="dragOptions"
                  handle=".item-dragable-icon"
                  class="drags-area"
                  chosenClass="chosen"
                  ghostClass="ghost"
                >
                  <li
                    v-for="(app, appIndex) in selectedApps"
                    :key="appIndex"
                    class="list-item"
                  >
                    <div class="app-icon item-dragable-icon">
                      <em
                        class="icon aufontAll h-icon-all-minus-circle opt-icon"
                        @click="delApp(app, appIndex)"
                      ></em>
                      <template v-if="app.content">
                        <img :src="'data:image/png;base64,' + app.content" />
                      </template>
                      <template v-else-if="app.logoUrl">
                        <img
                          v-if="app.logoUrl.indexOf('http') > -1"
                          :src="app.logoUrl"
                        />
                        <img v-else :src="getDownloadUrlNew(app.logoUrl)" />
                      </template>
                      <img v-else :src="defaultIcon" />
                    </div>
                    <div class="app-title" :title="getDisplayName(app)">
                      {{ getDisplayName(app) }}
                    </div>
                  </li>
                </draggable>
              </ul>
            </div>
            <div v-else class="empty-content">
              {{ $t('languages.common.workbanch.addTips') }}
            </div>
          </div>
          <div class="body-bottom">
            <div class="sub-title">
              {{ $t('languages.common.workbanch.addable') }}
            </div>
            <div v-if="appGroupList.length > 0" class="sub-content">
              <template v-for="(appGroup, index) in appGroupList">
                <div :key="index">
                  <div class="app-group-name" @click="onAppCollapse(appGroup)">
                    <em
                      class="icon aufontAll caret-icon"
                      :class="
                        appGroup.collapse
                          ? 'h-icon-all-caret-right'
                          : 'h-icon-all-caret-down'
                      "
                    ></em>
                    <!-- {{ appGroup.name }} -->
                    {{ getDisplayName(appGroup) }}
                  </div>
                  <ul class="app-list" :class="{ collapse: appGroup.collapse }">
                    <template v-for="(app, appIndex) in appGroup.children">
                      <li
                        v-if="!app.selected"
                        :key="appIndex"
                        class="list-item"
                        @click="addApp(app)"
                      >
                        <div class="app-icon">
                          <em
                            class="icon aufontAll h-icon-all-plus-circle opt-icon"
                            :class="{
                              disabled: selectedApps.length >= maxFavoritesApps,
                            }"
                          ></em>
                          <template v-if="app.content">
                            <img
                              :src="'data:image/png;base64,' + app.content"
                            />
                          </template>
                          <template v-else-if="app.logoUrl">
                            <img
                              v-if="app.logoUrl.indexOf('http') > -1"
                              :src="app.logoUrl"
                            />
                            <img v-else :src="getDownloadUrlNew(app.logoUrl)" />
                          </template>
                          <img v-else :src="defaultIcon" />
                        </div>
                        <div class="app-title" :title="getDisplayName(app)">
                          {{ getDisplayName(app) }}
                        </div>
                      </li>
                    </template>
                  </ul>
                </div>
              </template>
            </div>
          </div>
        </div>
        <div class="manage-edit-foot">
          <H3Button class="btn" type="default" @click="popupClose">{{
            $t('languages.common.cancel')
          }}</H3Button>
          <H3Button class="btn" type="primary" @click="onSave">{{
            $t('languages.common.ok')
          }}</H3Button>
        </div>
      </div>
    </h3-popup>
  </div>
</template>

<script lang="ts">
import { Component, Vue } from 'vue-property-decorator';
import { Mutation } from 'vuex-class';
import getDownloadUrlNew from 'cloudpivot/common/src/utils/getDownloadUrlNew';
import { H3Popup, H3Button } from '@h3/thinking-ui';
import DefaultContent from './default-content.vue';
import Draggable from 'vuedraggable';
import { listApi } from 'cloudpivot/api';
import common from 'cloudpivot/common/mobile';
const icon = require('../assets/app-default-icon.png');

enum BizObjectType {
  APP_PACKAGE = 1,
  WORKFLOW = 2,
  BIZ_MODEL = 3,
}

@Component({
  name: 'myApplication',
  components: {
    H3Popup,
    DefaultContent,
    Draggable,
    H3Button,
    LoadingSkeleton: common.components.LoadingSkeleton,
  },
})
export default class myApplication extends Vue {
  @Mutation('setAppName') setAppName!: any;

  defaultIcon: string = icon; // 更多应用默认图标

  favoritesApps: any[] = []; //收藏应用

  manageEdit: boolean = false; //编辑状态

  selectedApps: any[] = []; //当前已添加的应用

  appGroupList: any[] = []; //所有应用

  loading: boolean = true;

  dragOptions: any = {
    animation: 150,
    ghostClass: 'ghostClass',
    forceFallback: true,
    fallbackClass: 'dragClass',
    touchStartThreshold: 20,
    delay: 100,
  };

  maxFavoritesApps: number = 12; //最大可管理应用数量

  page: number = 0;

  size: number = 50;

  openPage: boolean = true;

  openScroll: boolean = true;

  isLoading: boolean = true;

  load(flag?: boolean) {
    if (flag) {
      this.loading = false;
      this.$h3.toast.hide();
    } else {
      this.loading = true;
      this.$h3.toast.show({
        text: this.$t('languages.common.workbanch.loading'),
        iconType: 'loading',
        autoHide: false,
      });
    }
  }

  created() {
    this.initFavoriteApps();
  }

  onScroll() {
    const dom: any = document.getElementsByClassName('manage-edit-body')[0];
    if (dom && dom.addEventListener) {
      dom.addEventListener('scroll', (x) => {
        const scrollTop = dom.scrollTop;
        const scrollHeight = dom.scrollHeight;
        const offsetHeight = dom.offsetHeight;
        if (
          scrollTop + offsetHeight >= scrollHeight &&
          this.openPage &&
          this.openScroll
        ) {
          this.page++;
          this.getApplist();
        }
      });
    } else {
      setTimeout(() => {
        this.onScroll();
      }, 500);
    }
  }

  /**
   * 获取所有已添加到我的常用
   */
  initFavoriteApps() {
    this.listFavorite().then((res: any) => {
      if (res.errcode === 0) {
        this.favoritesApps =
          res.data?.map((item) => {
            return {
              ...item,
              type: this.transferType(item.metadataType),
              name: item.name || item.appName,
              name_i18n: item.name_i18n || item.appName_i18n,
              code: item.code || item.appCode,
              logoUrl: !this.transferType(item.metadataType) ? item.logo : '',
              icon: this.transferType(item.metadataType) ? item.logo : '',
            };
          }) || [];
      }
      this.isLoading = false;
    });
  }

  transferType(backType) {
    if (backType === 'APP') {
      return null;
    } else if (backType === 'REPORT_DASHBOARD') {
      return 'Report';
    } else if (backType === 'BIZ_SCHEMA') {
      return 'BizModel';
    } else {
      return backType;
    }
  }

  async listFavorite() {
    return listApi.listFavorite({ isMobile: true });
  }

  /**
   * 跳转到应用分组
   */
  async appRoute(app) {
    const name = common.utils.BusinessFunctions.getLangName(app);
    this.setAppName(name);
    this.$router
      .push({
        name: 'app-item',
        params: {
          appCode: app.code,
        },
      })
      .catch((err: any) => {
        console.log(err);
      });
  }

  /**
   * 名称转换
   */
  getDisplayName(item) {
    let name: string = item.name;
    let name_i18n: any = item.name_i18n || item.appName_i18n;
    if (name_i18n) {
      const name_i18ns =
        typeof name_i18n === 'object' ? name_i18n : JSON.parse(name_i18n);
      name = name_i18ns[this.$i18n.locale] || name;
    }
    return name;
  }

  getDownloadUrlNew(refId: string) {
    return getDownloadUrlNew.getImageUrl(refId);
  }

  onManageEdit() {
    this.manageEdit = true;
    this.selectedApps = [...this.favoritesApps];
    setTimeout(() => {
      this.onScroll();
    }, 50);
    this.page = 0;
    this.openPage = true;
    this.appGroupList = [];
    this.getApplist();
  }

  /**
   * 取消勾选，不保存任何
   */
  popupClose() {
    this.manageEdit = false;
    this.selectedApps = [];

    this.appGroupList.forEach((group) => {
      this.$set(group, 'collapse', false);
    });
  }

  /**
   * 保存添加收藏的应用
   */
  onSave() {
    const navigatorList = this.selectedApps.map((item: any, index: number) => {
      return {
        code: item.code,
        type: item.type ? BizObjectType.BIZ_MODEL : BizObjectType.APP_PACKAGE,
        sortKey: index,
      };
    });

    listApi
      .createFavorite({
        userFavoriteList: navigatorList,
        isMobile: true,
      })
      .then((res: any) => {
        if (res.errcode === 0) {
          this.listFavorite().then((innerRes: any) => {
            if (innerRes.errcode === 0) {
              this.favoritesApps =
                innerRes.data?.map((item) => {
                  return {
                    ...item,
                    type: this.transferType(item.metadataType),
                    name: item.name || item.appName,
                    name_i18n: item.name_i18n || item.appName_i18n,
                    code: item.code || item.appCode,
                    logoUrl: !this.transferType(item.metadataType)
                      ? item.logo
                      : '',
                    icon: this.transferType(item.metadataType) ? item.logo : '',
                  };
                }) || [];
              this.manageEdit = false;
            }
          });
        }
      });
  }

  /**
   * 获取所有应用
   */
  async getApplist() {
    this.openScroll = false;
    this.load();
    const res = await listApi.listByGroupPage({
      isMobile: true,
      page: this.page,
      size: this.size,
    });
    if (res.errcode === 0) {
      let appGroupArr = res.data.content.filter((x) => {
        return x.code !== 'all';
      });
      appGroupArr.forEach((group) => {
        if (group.children && Array.isArray(group.children)) {
          group.children.forEach((item) => {
            item.displayName = common.utils.BusinessFunctions.getLangName(item);
            item.selected = this.selectedApps.some((nav) => {
              return nav.code === item.code;
            });
          });
        }

        //设置分组折叠属性
        this.$set(group, 'collapse', false);
      });
      if (this.page + 1 >= res.data.totalPages) {
        this.openPage = false;
      }
      if (this.page) {
        if (appGroupArr.length) {
          let arrData = this.appGroupList.filter((x) => {
            return x.code === appGroupArr[0].code;
          });

          if (arrData.length > 0) {
            arrData[0].children = arrData[0].children.concat(
              appGroupArr[0].children,
            );
            appGroupArr.shift();
          }
        }
        this.appGroupList = this.appGroupList.concat(appGroupArr);
      } else {
        this.appGroupList = appGroupArr;
      }
    }
    setTimeout(() => {
      this.openScroll = true;
    }, 500);
    this.load(true);
  }

  /**
   * 应用分组折叠
   */
  onAppCollapse(appGroup) {
    appGroup.collapse = !appGroup.collapse;
  }

  /**
   * 应用点击事件
   */
  addApp(app) {
    if (this.selectedApps.length >= this.maxFavoritesApps) {
      return;
    }
    this.selectedApps.push(app);
    this.appSelectedControl(app, true);
  }

  /**
   * 删除已添加的应用
   */
  delApp(app, index) {
    this.selectedApps.splice(index, 1);
    this.appSelectedControl(app, false);
  }

  /**
   * 控制所有应用选择状态
   */
  appSelectedControl(app, selectedFlag) {
    this.appGroupList = this.appGroupList.map((group) => {
      if (group.children && Array.isArray(group.children)) {
        group.children.forEach((item) => {
          if (app.code === item.code) {
            item.selected = selectedFlag;
          }
        });
      }
      return group;
    });
  }
}
</script>
<style lang="less" scoped>
@import '~@/styles/mixins.less';
.my-application {
  display: flex;
  flex-direction: column;
  .px2remSmall(padding-left, 8px);
  .px2remSmall(padding-right, 8px);
  .px2remSmall(padding-top, 16px);
  .px2remSmall(padding-bottom, 16px);
  .px2remSmall(margin-top, 12px);
  .px2remSmall(margin-bottom, 12px);
  > .header {
    .px2remSmall(padding-left, 12px);
    .px2remSmall(padding-right, 12px);
  }
  /deep/.box-third {
    margin-bottom: 0;
    padding: 8px 20px;
  }
}

.app-list {
  padding-top: 10px;
  margin-bottom: 0;
  flex-wrap: wrap;
  display: flex;
  .drags-area {
    flex-wrap: wrap;
    display: flex;
    width: 100%;
  }
  .list-item {
    flex-basis: 25%;
    .px2rem(margin-bottom, 16px);
    text-align: center;
    padding: 6px 4px;
    .app-title {
      margin: 0 auto;
      // width: 5em;
      .px2rem(max-width, 152px);
      .px2rem(max-height, 65px);
      .px2rem(font-size, 24px);
      .px2rem(line-height, 33px);
      text-align: center;
      display: -webkit-box;
      /*! autoprefixer: ignore next */
      -webkit-box-orient: vertical;
      /* autoprefixer: on */
      -webkit-line-clamp: 2;
      overflow: hidden;
      word-break: break-all;
      color: #111218;
      pointer-events: none;
      -webkit-user-select: none;
      user-select: none;
    }
    .app-icon {
      position: relative;
      cursor: pointer;
      display: flex;
      align-items: center;
      justify-content: center;
      margin-left: auto;
      margin-right: auto;
      .px2rem(width, 88px);
      .px2rem(height, 88px);
      .px2rem(margin-bottom, 20px);
      .px2rem(border-radius, 12px);
      img,
      svg {
        pointer-events: none;
        width: 100%;
        height: 100%;
        .px2rem(border-radius, 12px);
      }
      -webkit-user-select: none;
      user-select: none;
    }
    .opt-icon {
      position: absolute;
      top: -10px;
      right: -10px;
      color: #2970ff;
      font-size: 18px;
    }
    .opt-icon.disabled {
      color: #c3c4c5;
    }
    .h-icon-all-minus-circle {
      color: #f0353f;
    }
  }
  .list-item.chosen {
    background: rgba(41, 112, 255, 0.08);
    border-radius: 6px;
    .h-icon-all-minus-circle {
      display: none;
    }
  }
}

.app-list.collapse {
  display: none;
}

.caret-icon {
  display: inline-block;
  transform: scale(0.5);
}
</style>
